home *** CD-ROM | disk | FTP | other *** search
- /************************************************************
- Module name: DIPSLib.c
- Notices: Copyright (c) 1996 Jeffrey Richter
- Change Log: Assorted changes by Dave Jewell for Delphi
- ************************************************************/
-
- #include "CmnHdr.H"
- #include <Windows.H>
- #include <WindowsX.H>
- #include <CommCtrl.H>
- #include "Resource.H"
-
- HINSTANCE g_hinstDll = NULL;
-
- //--------------------------------------------------------------------------
- // This segment is shared by all applications that use the DLL
- //--------------------------------------------------------------------------
-
- #pragma data_seg("Shared")
- HHOOK hHook = NULL;
- DWORD dwApplicationThread = 0; // thread ID of application which called SetDIPSHook
- char szSharedBuff [256];
-
-
-
- static const TCHAR g_szRegSubKey[] = __TEXT ("Software\\Richter\\Desktop Item Position Saver");
-
- #pragma data_seg()
- #pragma comment(linker, "/section:Shared,rws")
-
- //--------------------------------------------------------------------------
-
- void SaveListViewItemPositions(HWND hwndLV)
- {
- int nItem, nMaxItems = ListView_GetItemCount(hwndLV);
- HKEY hkey;
- DWORD dwDisposition;
-
- // When saving new positions, delete the old position
- // information that is currently in the registry.
- RegDeleteKey (HKEY_CURRENT_USER, g_szRegSubKey);
-
- // Create the registry key to hold the info
- RegCreateKeyEx (HKEY_CURRENT_USER, g_szRegSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hkey, &dwDisposition);
-
- for (nItem = 0; nItem < nMaxItems; nItem++)
- {
- TCHAR szName[_MAX_PATH];
- POINT pt;
-
- // Get the name and position of a listview item.
- ListView_GetItemText (hwndLV, nItem, 0, szName, chDIMOF(szName));
- ListView_GetItemPosition (hwndLV, nItem, &pt);
-
- // Save the name and position in the registry.
- RegSetValueEx (hkey, szName, 0, REG_BINARY, (PBYTE) &pt, sizeof(pt));
- }
-
- RegCloseKey(hkey);
- }
-
- //--------------------------------------------------------------------------
-
- void RestoreListViewItemPositions (HWND hwndLV)
- {
- HKEY hkey;
- LONG l = RegOpenKeyEx(HKEY_CURRENT_USER, g_szRegSubKey,
- 0, KEY_QUERY_VALUE, &hkey);
- if (l == ERROR_SUCCESS) {
- int nIndex;
-
- // If the listview has AutoArrange on,
- // temporarily turn it off.
- DWORD dwStyle = GetWindowStyle (hwndLV);
- if (dwStyle & LVS_AUTOARRANGE) SetWindowLong (hwndLV, GWL_STYLE, dwStyle & ~LVS_AUTOARRANGE);
-
- l = NO_ERROR;
- for (nIndex = 0; l != ERROR_NO_MORE_ITEMS; nIndex++) {
- TCHAR szName[_MAX_PATH];
- POINT pt;
- LV_FINDINFO lvfi;
- int cbValueName = chDIMOF(szName);
- int cbData = sizeof(pt), nItem;
- DWORD dwType;
-
- // Read a value name and position from the registry.
- l = RegEnumValue(hkey, nIndex, szName, &cbValueName,
- NULL, &dwType, (PBYTE) &pt, &cbData);
-
- if (l == ERROR_NO_MORE_ITEMS)
- continue;
-
- if ((dwType == REG_BINARY) && (cbData == sizeof(pt))) {
- // The value is something that we recognize; try to find
- // an item in the listview control that matches the name.
- lvfi.flags = LVFI_STRING;
- lvfi.psz = szName;
- nItem = ListView_FindItem(hwndLV, -1, &lvfi);
- if (nItem != -1) ListView_SetItemPosition(hwndLV, nItem, pt.x, pt.y);
- }
- }
- // Turn AutoArrange back on if it was originally on.
- SetWindowLong(hwndLV, GWL_STYLE, dwStyle);
- RegCloseKey(hkey);
- }
- }
-
- //--------------------------------------------------------------------------
-
- BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID fImpLoad)
- {
- if (fdwReason == DLL_PROCESS_ATTACH) g_hinstDll = hinstDll;
- return (TRUE);
- }
-
- //--------------------------------------------------------------------------
-
- void DIPS_OnClose (HWND hwnd)
- {
- DestroyWindow (hwnd);
- }
-
- BOOL WINAPI DIPS_DlgProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- switch (uMsg)
- {
- case WM_APP:
- if (lParam) SaveListViewItemPositions((HWND) wParam);
- else RestoreListViewItemPositions((HWND) wParam);
- break;
-
- chHANDLE_DLGMSG (hwnd, WM_CLOSE, DIPS_OnClose);
- }
-
- return (FALSE);
- }
-
- //--------------------------------------------------------------------------
-
- LRESULT WINAPI GetMsgProc (int nCode, WPARAM wParam, LPARAM lParam)
- {
- static BOOL fFirstTime = TRUE;
-
- if (fFirstTime)
- {
- fFirstTime = FALSE;
- // Create the server window to service client requests
- CreateDialog (g_hinstDll, MAKEINTRESOURCE (IDD_DIPS), NULL, DIPS_DlgProc);
- // Tell the original application that server is ready
- PostThreadMessage (dwApplicationThread, WM_NULL, 0, 0);
- }
-
- return (CallNextHookEx (hHook, nCode, wParam, lParam));
- }
-
- //--------------------------------------------------------------------------
-
- __declspec (dllexport) BOOL WINAPI SetDIPSHook(DWORD dwThreadId)
- {
- BOOL fOk = FALSE;
-
- if (dwThreadId != 0)
- {
- // Save our thread ID in a shared variable so that
- // our GetMsgProc function can post a message back to
- // to thread when the server window has been created.
- dwApplicationThread = GetCurrentThreadId();
-
- // Install the hook on the specified thread
- hHook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, g_hinstDll, dwThreadId);
- fOk = (hHook != NULL);
- if (fOk) {
- // The hook was installed successfully; force a
- // benign message to the thread's queue so that
- // the hook function gets called.
- fOk = PostThreadMessage(dwThreadId, WM_NULL, 0, 0);
- }
- }
- else
- {
- fOk = UnhookWindowsHookEx(hHook);
- hHook = NULL;
- }
-
- return(fOk);
- }
-
-